
namespace Patterns4Net.PatternEnforcer.Core
{
    using System.Diagnostics.Contracts;
    using Attributes.DesignPatterns;

    /// <summary>
    /// Represents a strategy for checking correctness of thing that is represented by given object.
    /// Checkers are used for checking of types, methods and patterns.
    /// </summary>
    /// <typeparam name="T">The type of objects to be checked.</typeparam>
    [Strategy]    
    [ContractClass(typeof(CheckerContract<>))]
    public interface IChecker<in T> where T : class
    {
        /// <summary>
        /// Checks that <paramref name="subject"/> conforms to this specification.
        /// </summary>
        CheckerResult Check(T subject);
    }

    /// <summary>
    /// Defines the contract for the <see cref="IChecker{T}"/> class.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    [ContractClassFor(typeof(IChecker<>))]
    public abstract class CheckerContract<T> : IChecker<T> where T : class
    {
        public CheckerResult Check(T subject)
        {
            Contract.Requires(subject != null);
            Contract.Ensures(Contract.Result<CheckerResult>() != null);
            return null;
        }
    }
}
